package com.cjh.mybatis02.bind;

import cn.hutool.core.lang.ClassScanner;
import com.cjh.mybatis02.session.SqlSession;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;


/**
 * @Descripton
 * @Author cjh
 * @Date 2023/5/24 15:10
 */
public class MapperRegistry {
    /**
     * 将已添加的映射器代理工厂加入到 HashMap
     */
    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

    public boolean hasMapper(Class<?> type) {
        return knownMappers.containsKey(type);
    }

    public void addMappers(String packageName) {
        Set<Class<?>> mapperSet = ClassScanner.scanPackage(packageName);

        for (Class<?> mapperClass : mapperSet) {
            addMapper(mapperClass);

        }


    }

    public <T> void addMapper(Class<T> type) {
        /**
         * mapper 是接口才能被注册
         */
        if (type.isInterface()) {
            if (hasMapper(type)) {
                throw new RuntimeException("type:" + "is already known to the MapperRegistry. ");
            }
//           注册映射器代理工厂
            knownMappers.put(type, new MapperProxyFactory<>(type));
        }
    }


    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);

        if (mapperProxyFactory == null) {
            throw new RuntimeException("Type " + type + " is not known to the MapperRegistry.");

        }

        try {
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            throw new RuntimeException("Error getting mapper instance. Cause: " + e, e);

        }

    }

}
